# GPL3 or any later version

import os
import json
import time

import gi
import threading
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from gi.repository import Gdk
from gi.repository import GLib

from modules import wallet
from modules import images
from modules import ui


def select_dialogue(win, mode="normal"):

    # This is an item selector.

    dialogWindow = Gtk.Dialog("Select Merchant",
            buttons=(),
        )
    dialogWindow.set_size_request(400, 400)
    r = Gtk.VBox()
    r.ret = None
    
    def todo(w, win, item):
        r.ret = item
        dialogWindow.destroy()
    
    box = dialogWindow.get_content_area()
    select_widget(win, box, todo, mode=mode)


    
    box.show_all()
    response = dialogWindow.run()
    dialogWindow.destroy()
    return r.ret
    
def select_widget(win, box, todo, mode="normal"):

    # Draws widget for searching and selecting items.

    search_box = Gtk.HBox()
    box.pack_start(search_box, 0,0,1)
    
    def on_changed(w):
        win.search_item = search.get_text()

    def on_search(w):
        refresh_items(win, pack, todo, search=search.get_text())
        
    search = Gtk.Entry()
    search.connect("changed", on_changed)
    search.connect("activate", on_search)
    search_box.pack_start(search, 1,1,0)
    
    scrl = Gtk.ScrolledWindow()
    scrl.set_vexpand(0)
    box.pack_start(scrl, 1,1,1)

    pack = Gtk.VBox()
    scrl.add(pack)

    refresh_items(win, pack, todo)
    return (win, pack, todo)

def refresh_items(win, pack, todo, search=""):

    for i in pack.get_children():
        i.destroy()
    
    flowbox = Gtk.FlowBox()
    flowbox.set_valign(Gtk.Align.START)
    flowbox.set_max_children_per_line(30)
    flowbox.set_selection_mode(Gtk.SelectionMode.NONE)

    
    def on_add_item(w):
        editor(win, new=True)
        refresh_items(win, pack, todo, search="")
    
    add_item = Gtk.Button()
    add_item.add(ui.icon(win, "list-add"))
    add_item.set_relief(Gtk.ReliefStyle.NONE)
    flowbox.add(add_item)
    add_item.connect("clicked", on_add_item)

    folder = wallet.save_folder()+"merchants/"

    try:
        items = list(os.walk(folder))[0][2]
        items = sorted(items)
    except:
        items = []
    
    for i in items:

        with open(folder+i) as json_file: 
            idata = json.load(json_file) 

        if search:
            if search.lower() not in idata.get("name").lower() and search.lower() not in i.lower():
                continue
            
        item_button = Gtk.Button()
        item_button.connect("clicked", todo, win, i)
        item_button.set_relief(Gtk.ReliefStyle.NONE)
        item_box = Gtk.VBox()
        item_button.add(item_box)
        save_as = idata.get("image", "")
        if os.path.exists(save_as):
            image = ui.load(win, ui.net_image_calculation, ui.net_image_render, "", 100 , save_as, False)
        else:
            image = ui.icon(win, "go-home")
        item_box.pack_start(image, 0,0,0)
        item_box.pack_start(Gtk.Label(str(idata.get("name", ""))), 0,0,0)
        item_box.pack_start(Gtk.Label(str(idata.get("address", ""))),0,0,0)
        flowbox.add(item_button)

    
    flowbox.show_all()
    pack.pack_start(flowbox, 1,1,1)

def editor(win, item="", new=False):

    # editor

    folder = wallet.save_folder()+"merchants/"
    try:
        os.makedirs(folder)
    except:
        pass

    data = {}
    edit_id = True

    try:
        search = win.search_item
    except:
        search = ""

    if not item:
        item = search
        
    if item:
        try:
            if not item.endswith(".json"):
                item = item+".json"
            with open(folder+item) as json_file: 
                data = json.load(json_file)
            item = item.replace(".json", "")
            edit_id = False
        except:
            pass
        
    
    if not data:
        
        data = {
            "name":"",
            "image":"",
            "address":"",
            "phone":"",
            "email":""}

        
        try:
            item = str(int(search))
        except:
            data["name"] = search
        
    
    dialogWindow = Gtk.Dialog("Merchant",
            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                     Gtk.STOCK_OK, Gtk.ResponseType.OK),
        )
    dialogWindow.set_size_request(200, 200)
    
    box = dialogWindow.get_content_area()

    main_data_box = Gtk.HBox()
    box.pack_start(main_data_box, 1,1,1)

    # IMAGE

    def image_edit(w):

        search = address_entry.get_text()+" "+name_entry.get_text()

        if search:
            images.select_image(win, search)
            save_as = win.return_search
            data["image"] = save_as
            add_image.get_children()[0].destroy()
            
            image = ui.load(win, ui.net_image_calculation, ui.net_image_render, "", 100 , save_as, False)
            add_image.add(image)
            add_image.show_all()
        
    add_image = Gtk.Button()
    main_data_box.pack_start(add_image, 0,0,0)
    add_image.connect("clicked", image_edit)
    
    if not data.get("image"):
        add_image.add(ui.icon(win, "image-x-generic"))
        add_image.set_relief(Gtk.ReliefStyle.NONE)
    else:
        save_as = data.get("image")
        image = ui.load(win, ui.net_image_calculation, ui.net_image_render, "", 100 , save_as, False)
        add_image.add(image)
        
    text_data_box = Gtk.VBox()
    main_data_box.pack_start(text_data_box, 1,1,1)

    # ID

    def on_entry(w, d):
        data[d] = w.get_text()


        
    id_box = Gtk.HBox()
    text_data_box.pack_start(id_box, 0,0,5)
    id_box.pack_start(Gtk.Label(" ID: "), 0,0,0)
    id_entry = Gtk.Entry()
    id_entry.grab_focus()
    id_entry.set_sensitive(edit_id)
    
    id_box.pack_end(id_entry, 0,0,0)

    # NAME

    name_box = Gtk.HBox()
    text_data_box.pack_start(name_box, 0,0,5)
    name_box.pack_start(Gtk.Label(" Name: "), 0,0,0)
    name_entry = Gtk.Entry()
    name_entry.connect("changed", on_entry, "name")
    name_box.pack_end(name_entry, 0,0,0)

    # Address

    address_box = Gtk.HBox()
    text_data_box.pack_start(address_box, 0,0,5)
    address_box.pack_start(Gtk.Label(" Address: "), 0,0,0)
    address_entry = Gtk.Entry()
    address_entry.connect("changed", on_entry, "address")
    address_box.pack_end(address_entry, 0,0,0)
    
    # Phone

    phone_box = Gtk.HBox()
    text_data_box.pack_start(phone_box, 0,0,5)
    phone_box.pack_start(Gtk.Label(" Phone: "), 0,0,0)
    phone_entry = Gtk.Entry()
    phone_entry.connect("changed", on_entry, "phone")
    phone_box.pack_end(phone_entry, 0,0,0)

    # Email

    email_box = Gtk.HBox()
    text_data_box.pack_start(email_box, 0,0,5)
    email_box.pack_start(Gtk.Label(" Email: "), 0,0,0)
    email_entry = Gtk.Entry()
    email_entry.connect("changed", on_entry, "email")
    email_box.pack_end(email_entry, 0,0,0)

    
    # Auto filling

    if item:
        id_entry.set_text( str(item).replace(".json", "") )
        name_entry.grab_focus()

    name_entry.set_text(str(data.get("name", "")))
    address_entry.set_text(str(data.get("address", "")))
    phone_entry.set_text(str(data.get("phone", "")))
    email_entry.set_text(str(data.get("email", "")))


    box.show_all()
    
    response = dialogWindow.run()
    if response == Gtk.ResponseType.OK:

        item = id_entry.get_text()

        if new: # Failsafe for in case the user will accidentaly overwrite
            n = 0 # an existing item by mistake. 
            nn = item
            while os.path.exists(folder+str(item)+".json"):
                n = n + 1
                item = nn+"_"+str(n)
        
        filename = folder+str(item)+".json"
        with open(filename, "w") as fp:
            json.dump(data, fp, indent=4)

    dialogWindow.destroy()
